Skip to content

chore(io): check a compio stream's descriptor before each raw use - #166

Merged
lexoliu merged 4 commits into
mainfrom
fix/159-empty-region
Nov 11, 2026
Merged

lexoliu merged 4 commits into
mainfrom
fix/159-empty-region

Conversation

@lexoliu

@lexoliu lexoliu commented Nov 11, 2026

Copy link
Copy Markdown
Collaborator

Diagnostics for #159, where a file region's bytes left the server as reported sent yet never reached the client. Reading the send path rules out a zero-byte result taken as done, reads at the shared file offset and a dropped response; what remains is a raw-descriptor syscall (the pipe drain, to_pipe/from_pipe, FIONBIO, AsFd) acting on a number that no longer names the stream's socket while slot-addressed operations still reach it.

In debug builds a compio stream now records its socket's identity (st_dev/st_ino/type) and checks it before each use of the raw number, panicking with what the number names instead; operations addressed through the registered slot are not checked, since their number does not matter. h1 also records when a file region has finished sending, so a trace that ends at sending a file region now means the send never finished. A test puts a file over a stream's number with dup2 and expects the check to fire.

Refs #159

A region's log ended at "sending a file region" whether the socket took
it whole or the send never finished, so a server's record could not tell
a body that went out from one that did not. The connection now records
the region's end as well.

Refs #159
A file region on compio once reached the peer as a 200 head, no body and a
clean FIN. The head and the shutdown name the socket by its slot in the
ring's file table, while the body's splice names it by descriptor number;
both reaching the peer except the body fits a number closed and reused
while the slot kept the socket open.

Debug builds now record the socket's device and inode when a stream is
made and compare them before every use of the number: each raw splice,
FIONBIO, the AsFd handed to kTLS and to callers, and each operation
submitted through the slot holder. A mismatch panics naming what the
number now holds, so the next failure points at the reuse instead of
losing bytes.

Refs #159
An operation submitted while the stream holds its slot names the socket
by the slot, so the number may legitimately point elsewhere then (the
registered-slot test points it at /dev/null). The identity check moves
into the slot holder and runs only for an operation that names the
descriptor; raw syscalls and AsFd keep theirs.

Refs #159
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 85.24590% with 9 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
io/src/sys/unix.rs 70.00% 9 Missing ⚠️

📢 Thoughts on this report? Let us know!

@lexoliu
lexoliu merged commit 9b1903e into main Nov 11, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants